﻿namespace AC.ExtendedRenderer.Toolkit
{
    using AC.ExtendedRenderer.Toolkit.Drawing;
    using AC.ExtendedRenderer.Toolkit.Utils;
    using ComponentFactory.Krypton.Toolkit;
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Text;
    using System.Windows.Forms;

    [ToolboxBitmap(typeof(TreeView))]
    public class KryptonTreeView : TreeView
    {
        private bool _drawFocus;
        private bool _enableSelectionBorder = true;
        private bool _enableVistaCheckBoxes = true;
        private bool _enableVistaSigns = true;
        private bool _enableVisualSigns = true;
        private bool _flatDesign;
        private Color _flatDesignColor = Color.Gray;
        private Color _flatDesignColorLostFocus = Color.FromArgb(0xe7, 0xe7, 0xe7);
        private Color _flatDesignColorTmp = Color.Gray;
        private LinearGradientMode _gradientDirection = LinearGradientMode.Vertical;
        private Color _gradientEndColor = Color.Gray;
        private Color _gradientEndColorLostFocus = Color.LightGray;
        private Color _gradientEndColorStyled = Color.Gray;
        private Color _gradientEndColorTmp = Color.Gray;
        private Color _gradientStartColor = Color.White;
        private Color _gradientStartColorLostFocus = Color.WhiteSmoke;
        private Color _gradientStartColorStyled = Color.White;
        private Color _gradientStartColorTmp = Color.White;
        private Color _nodeFocusColor = Color.Gray;
        private Color _nodeTextColor = Color.Gray;
        private Color _nodeTextColorTmp = Color.Gray;
        private IPalette _palette;
        private PaletteRedirect _paletteRedirect;
        private bool _persistentColors;
        private bool _useStyledColors;
        private IContainer components;
        private ImageList ilCheckBoxes;
        private ImageList ilSigns;
        private Font tagFont = new Font("Helvetica", 8f, FontStyle.Bold);
        private static int WM_ERASEBKGND = 20;
        private static int WM_NCPAINT = 0x85;
        private static int WM_PAINT = 15;

        public KryptonTreeView()
        {
            base.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
            base.UpdateStyles();
            base.DrawMode = TreeViewDrawMode.OwnerDrawAll;
            if (this._palette != null)
            {
                this._palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(this.OnPalettePaint);
            }
            KryptonManager.GlobalPaletteChanged += new System.EventHandler(this.OnGlobalPaletteChanged);
            this._palette = KryptonManager.CurrentGlobalPalette;
            this._paletteRedirect = new PaletteRedirect(this._palette);
            this._enableVistaCheckBoxes = Utility.IsVista();
            this._enableVistaSigns = Utility.IsVista();
            this.InitColors();
            this.InitializeComponent();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this._palette != null)
                {
                    this._palette.PalettePaint -= new EventHandler<PaletteLayoutEventArgs>(this.OnPalettePaint);
                    this._palette = null;
                }
                KryptonManager.GlobalPaletteChanged -= new System.EventHandler(this.OnGlobalPaletteChanged);
            }
            base.Dispose(disposing);
        }

        public void DrawBack(ref Message message, int width, int height)
        {
            if (((message.Msg == WM_NCPAINT) || (message.Msg == WM_ERASEBKGND)) || (message.Msg == WM_PAINT))
            {
                IntPtr hdc = Win32.GetDCEx(message.HWnd, (IntPtr) 1, 0x21);
                if (hdc != IntPtr.Zero)
                {
                    Graphics graphics = Graphics.FromHdc(hdc);
                    Rectangle rect = new Rectangle(0, 0, width, height);
                    graphics.FillRectangle(new SolidBrush(Color.Transparent), rect);
                    message.Result = (IntPtr) 1;
                    Win32.ReleaseDC(message.HWnd, hdc);
                }
            }
        }

        private void InitColors()
        {
            if (!this._persistentColors)
            {
                this._gradientStartColor = this._palette.ColorTable.StatusStripGradientBegin;
                this._gradientEndColor = this._palette.ColorTable.OverflowButtonGradientEnd;
                this._gradientStartColorTmp = this._palette.ColorTable.StatusStripGradientBegin;
                this._gradientEndColorTmp = this._palette.ColorTable.OverflowButtonGradientEnd;
                this._gradientStartColorStyled = Color.FromArgb(0xff, 0xf6, 0xd7);
                this._gradientEndColorStyled = Color.FromArgb(0xff, 0xd5, 0x4d);
                this._nodeTextColor = this._palette.ColorTable.StatusStripText;
                this._nodeTextColorTmp = this._palette.ColorTable.StatusStripText;
                this._nodeFocusColor = this._palette.ColorTable.ToolStripGradientEnd;
                if (this._useStyledColors)
                {
                    this._nodeTextColor = Color.Black;
                    this._nodeFocusColor = Color.FromArgb(0xff, 0xd5, 0x4d);
                }
                if (this._flatDesign)
                {
                    this._nodeTextColor = Color.Black;
                    this._nodeFocusColor = Color.Gray;
                }
            }
            this._nodeTextColorTmp = this._nodeTextColor;
            this._flatDesignColor = this._palette.ColorTable.OverflowButtonGradientMiddle;
            this._flatDesignColorTmp = this._palette.ColorTable.OverflowButtonGradientMiddle;
        }

        private void InitializeComponent()
        {
            this.components = new Container();
            ComponentResourceManager manager = new ComponentResourceManager(typeof(KryptonTreeView));
            this.ilSigns = new ImageList(this.components);
            this.ilCheckBoxes = new ImageList(this.components);
            base.SuspendLayout();
            this.ilSigns.ImageStream = (ImageListStreamer) manager.GetObject("ilSigns.ImageStream");
            this.ilSigns.TransparentColor = Color.Transparent;
            this.ilSigns.Images.SetKeyName(0, "XPPlus.png");
            this.ilSigns.Images.SetKeyName(1, "XPMinus.png");
            this.ilSigns.Images.SetKeyName(2, "VistaPlus.png");
            this.ilSigns.Images.SetKeyName(3, "VistaMinus.png");
            this.ilCheckBoxes.ImageStream = (ImageListStreamer) manager.GetObject("ilCheckBoxes.ImageStream");
            this.ilCheckBoxes.TransparentColor = Color.Transparent;
            this.ilCheckBoxes.Images.SetKeyName(0, "XpNotChecked.gif");
            this.ilCheckBoxes.Images.SetKeyName(1, "XpChecked.gif");
            this.ilCheckBoxes.Images.SetKeyName(2, "VistaNotChecked.png");
            this.ilCheckBoxes.Images.SetKeyName(3, "VistaChecked.png");
            base.LineColor = Color.Black;
            base.ResumeLayout(false);
        }

        private Rectangle NodeBounds(TreeNode node)
        {
            Rectangle rect = new Rectangle();
            if (node != null)
            {
                rect = node.Bounds;
                if (node.Tag != null)
                {
                    int num = ((int) base.CreateGraphics().MeasureString(node.Tag.ToString(), this.tagFont).Width) + 6;
                    rect.Offset(num / 2, 0);
                    rect = Rectangle.Inflate(rect, num / 2, 0);
                }
            }
            return rect;
        }

        protected override void OnDrawNode(DrawTreeNodeEventArgs e)
        {
            try
            {
                Image image;
                Image image2;
                string s = ">>";
                string str2 = "<<";
                string str3 = " ";
                if (this._enableVistaSigns)
                {
                    image = this.ilSigns.Images[2];
                    image2 = this.ilSigns.Images[3];
                }
                else
                {
                    image = this.ilSigns.Images[0];
                    image2 = this.ilSigns.Images[1];
                }
                Brush brush = new SolidBrush(this._nodeTextColor);
                Brush brush2 = new SolidBrush(this._nodeFocusColor);
                Graphics g = e.Graphics;
                Rectangle bounds = e.Bounds;
                try
                {
                    e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                }
                catch (Exception exception)
                {
                    Console.Write(exception.Message);
                }
                Rectangle rect = e.Bounds;
                rect.Height--;
                rect.Width--;
                Color color = this._gradientStartColor;
                Color color2 = this._gradientEndColor;
                if (!this._persistentColors)
                {
                    if (this._useStyledColors)
                    {
                        color = this._gradientStartColorStyled;
                        color2 = this._gradientEndColorStyled;
                    }
                    else
                    {
                        color = this._gradientStartColor;
                        color2 = this._gradientEndColor;
                    }
                }
                if ((((e.State & TreeNodeStates.Selected) != 0) || ((e.State & TreeNodeStates.Focused) != 0)) || ((e.State & TreeNodeStates.Checked) != 0))
                {
                    using (new LinearGradientBrush(e.Bounds, color, color2, LinearGradientMode.Vertical))
                    {
                        g.FillRectangle(Brushes.White, bounds);
                    }
                    if (this._flatDesign)
                    {
                        g.FillRectangle(new SolidBrush(this._flatDesignColor), bounds);
                    }
                    else
                    {
                        DrawingMethods.DrawGradient(g, rect, color, color2, 90f, this._enableSelectionBorder, color2, 1f);
                    }
                    Font nodeFont = e.Node.NodeFont;
                    if (nodeFont == null)
                    {
                        nodeFont = this.Font;
                    }
                    if (e.Node.Level != 0)
                    {
                        bounds.Offset(0x29 + (0x13 * (e.Node.Level - 1)), 0);
                        rect.Offset((0x29 + (0x13 * (e.Node.Level - 1))) - 0x12, 0);
                    }
                    else
                    {
                        bounds.Offset(0x16, 0);
                        rect.Offset(4, 0);
                    }
                    if (e.Node.Nodes.Count > 0)
                    {
                        if (e.Node.IsExpanded)
                        {
                            if (this._enableVisualSigns)
                            {
                                g.DrawImage(image2, rect.X - 1, rect.Y, 0x10, 0x10);
                            }
                            else
                            {
                                g.DrawString(str2, nodeFont, brush, rect);
                            }
                        }
                        else if (this._enableVisualSigns)
                        {
                            g.DrawImage(image, rect.X - 1, rect.Y, 0x10, 0x10);
                        }
                        else
                        {
                            g.DrawString(s, nodeFont, brush, rect);
                        }
                    }
                    else
                    {
                        g.DrawString(str3, nodeFont, brush, rect);
                    }
                    if (base.CheckBoxes)
                    {
                        Image image3;
                        if (e.Node.Checked)
                        {
                            if (this._enableVistaCheckBoxes)
                            {
                                image3 = this.ilCheckBoxes.Images[3];
                            }
                            else
                            {
                                image3 = this.ilCheckBoxes.Images[1];
                            }
                        }
                        else if (this._enableVistaCheckBoxes)
                        {
                            image3 = this.ilCheckBoxes.Images[2];
                        }
                        else
                        {
                            image3 = this.ilCheckBoxes.Images[0];
                        }
                        if (Utility.IsVista())
                        {
                            bounds.Offset(-2, -1);
                        }
                        g.DrawImage(image3, bounds.X, bounds.Y, 0x10, 0x10);
                        bounds.Offset(0x10, 0);
                        if (Utility.IsVista())
                        {
                            bounds.Offset(-1, 1);
                        }
                    }
                    if (((base.ImageList != null) && (e.Node.ImageIndex >= 0)) && (e.Node.ImageIndex < base.ImageList.Images.Count))
                    {
                        base.ImageList.Draw(g, bounds.X, bounds.Y, 0x10, 0x10, e.Node.ImageIndex);
                        bounds.Offset(0x13, 0);
                    }
                    else if (base.ImageList != null)
                    {
                        base.ImageList.Draw(g, bounds.X, bounds.Y, 0x10, 0x10, base.ImageIndex);
                        bounds.Offset(0x13, 0);
                    }
                    bounds.Offset(0, 1);
                    g.DrawString(e.Node.Text, nodeFont, brush, bounds);
                }
                else
                {
                    e.DrawDefault = true;
                }
                if (e.Node.Tag != null)
                {
                    e.Graphics.DrawString(e.Node.Tag.ToString(), this.tagFont, brush, (float) (e.Bounds.Right + 2), (float) e.Bounds.Top);
                }
                if ((e.State & TreeNodeStates.Focused) != 0)
                {
                    using (Pen pen = new Pen(brush2))
                    {
                        pen.DashStyle = DashStyle.Dash;
                        Rectangle rectangle3 = this.NodeBounds(e.Node);
                        rectangle3.Size = new Size(rectangle3.Width - 1, rectangle3.Height - 2);
                        if (this._drawFocus)
                        {
                            e.Graphics.DrawRectangle(pen, rectangle3);
                        }
                    }
                }
                brush.Dispose();
                brush2.Dispose();
            }
            catch
            {
            }
        }

        private void OnGlobalPaletteChanged(object sender, EventArgs e)
        {
            if (this._palette != null)
            {
                this._palette.PalettePaint -= new EventHandler<PaletteLayoutEventArgs>(this.OnPalettePaint);
            }
            this._palette = KryptonManager.CurrentGlobalPalette;
            this._paletteRedirect.Target = this._palette;
            if (this._palette != null)
            {
                this._palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(this.OnPalettePaint);
                this.InitColors();
            }
            base.Invalidate();
        }

        protected override void OnGotFocus(EventArgs e)
        {
            this._flatDesignColor = this._flatDesignColorTmp;
            this._nodeTextColor = this._nodeTextColorTmp;
            this._gradientStartColor = this._gradientStartColorTmp;
            this._gradientEndColor = this._gradientEndColorTmp;
            base.Invalidate();
            base.OnGotFocus(e);
        }

        protected override void OnLostFocus(EventArgs e)
        {
            this._flatDesignColor = this._flatDesignColorLostFocus;
            this._nodeTextColor = Color.Black;
            this._gradientStartColor = this._gradientStartColorLostFocus;
            this._gradientEndColor = this._gradientEndColorLostFocus;
            base.Invalidate();
            base.OnLostFocus(e);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            TreeNode nodeAt = base.GetNodeAt(e.X, e.Y);
            if (this.NodeBounds(nodeAt).Contains(e.X, e.Y))
            {
                base.SelectedNode = nodeAt;
            }
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            base.OnPaintBackground(pevent);
        }

        private void OnPalettePaint(object sender, PaletteLayoutEventArgs e)
        {
            base.Invalidate();
        }

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
        }

        [DefaultValue("false"), Browsable(true), Category("Appearance-Extended")]
        public bool DrawFocus
        {
            get
            {
                return this._drawFocus;
            }
            set
            {
                this._drawFocus = value;
                base.Invalidate();
            }
        }

        [Browsable(true), Category("Appearance-Extended"), DefaultValue("True")]
        public bool EnableSelectionBorder
        {
            get
            {
                return this._enableSelectionBorder;
            }
            set
            {
                this._enableSelectionBorder = value;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), Browsable(true), DefaultValue("True")]
        public bool EnableVistaCheckBoxes
        {
            get
            {
                return this._enableVistaCheckBoxes;
            }
            set
            {
                this._enableVistaCheckBoxes = value;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), Browsable(true), DefaultValue("True")]
        public bool EnableVistaSigns
        {
            get
            {
                return this._enableVistaSigns;
            }
            set
            {
                this._enableVistaSigns = value;
                base.Invalidate();
            }
        }

        [Browsable(true), Category("Appearance-Extended"), DefaultValue("True")]
        public bool EnableVisualSigns
        {
            get
            {
                return this._enableVisualSigns;
            }
            set
            {
                this._enableVisualSigns = value;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), Browsable(true), DefaultValue("False")]
        public bool FlatDesign
        {
            get
            {
                return this._flatDesign;
            }
            set
            {
                this._flatDesign = value;
                this.InitColors();
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), Browsable(true)]
        public Color FlatDesignColor
        {
            get
            {
                return this._flatDesignColor;
            }
            set
            {
                this._flatDesignColor = value;
                this._flatDesignColorTmp = value;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), Browsable(true)]
        public Color FlatDesignColorLostFocus
        {
            get
            {
                return this._flatDesignColorLostFocus;
            }
            set
            {
                this._flatDesignColorLostFocus = value;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), DefaultValue("Vertical"), Browsable(true)]
        public LinearGradientMode GradientDirection
        {
            get
            {
                return this._gradientDirection;
            }
            set
            {
                this._gradientDirection = value;
                base.Invalidate();
            }
        }

        [Browsable(true), DefaultValue("Color.Gray"), Category("Appearance-Extended"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Color GradientEndColor
        {
            get
            {
                return this._gradientEndColor;
            }
            set
            {
                this._gradientEndColor = value;
                this._gradientEndColorTmp = value;
                base.Invalidate();
            }
        }

        [Browsable(true), DefaultValue("Color.LightGray"), Category("Appearance-Extended")]
        public Color GradientEndColorLostFocus
        {
            get
            {
                return this._gradientEndColorLostFocus;
            }
            set
            {
                this._gradientEndColorLostFocus = value;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), Browsable(true), DefaultValue("Color.Gray")]
        public Color GradientEndColorStyled
        {
            get
            {
                return this._gradientEndColorStyled;
            }
            set
            {
                this._gradientEndColorStyled = value;
                base.Invalidate();
            }
        }

        [Browsable(true), DefaultValue("Color.White"), Category("Appearance-Extended"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Color GradientStartColor
        {
            get
            {
                return this._gradientStartColor;
            }
            set
            {
                this._gradientStartColor = value;
                this._gradientStartColorTmp = value;
                base.Invalidate();
            }
        }

        [DefaultValue("Color.WhiteSmoke"), Browsable(true), Category("Appearance-Extended")]
        public Color GradientStartColorLostFocus
        {
            get
            {
                return this._gradientStartColorLostFocus;
            }
            set
            {
                this._gradientStartColorLostFocus = value;
                base.Invalidate();
            }
        }

        [Browsable(true), Category("Appearance-Extended"), DefaultValue("Color.White")]
        public Color GradientStartColorStyled
        {
            get
            {
                return this._gradientStartColorStyled;
            }
            set
            {
                this._gradientStartColorStyled = value;
                base.Invalidate();
            }
        }

        [Browsable(true), Category("Appearance-Extended")]
        public Color NodeFocusColor
        {
            get
            {
                return this._nodeFocusColor;
            }
            set
            {
                this._nodeFocusColor = value;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), Browsable(true)]
        public Color NodeTextColor
        {
            get
            {
                return this._nodeTextColor;
            }
            set
            {
                this._nodeTextColor = value;
                this._nodeTextColorTmp = value;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), DefaultValue("False"), Browsable(true)]
        public bool PersistentColors
        {
            get
            {
                return this._persistentColors;
            }
            set
            {
                this._persistentColors = value;
                this.InitColors();
                base.Invalidate();
            }
        }

        [DefaultValue("False"), Browsable(true), Category("Appearance-Extended")]
        public bool UseStyledColors
        {
            get
            {
                return this._useStyledColors;
            }
            set
            {
                this._useStyledColors = value;
                this.InitColors();
                base.Invalidate();
            }
        }
    }
}

